package response

import (
	"fmt"
	"net/http"
	"time"

	"baseService/internal/pkg/errors"
	"github.com/gin-gonic/gin"
)

// ResponseCode 响应码类型
type ResponseCode int

const (
	CodeTokenExpired ResponseCode = 4010 // Token过期专用响应码

	CodeTokenInvalid ResponseCode = 4011 // Token无效

	// 成功响应码
	CodeSuccess ResponseCode = 200

	// 客户端错误码 4xx
	CodeBadRequest      ResponseCode = 400
	CodeUnauthorized    ResponseCode = 401
	CodeForbidden       ResponseCode = 403
	CodeNotFound        ResponseCode = 404
	CodeValidationError ResponseCode = 422
	CodeTooManyRequests ResponseCode = 429

	// 服务端错误码 5xx
	CodeInternalError ResponseCode = 500
	CodeServiceError  ResponseCode = 503
	CodeTimeout       ResponseCode = 504
)

// BaseResponse 基础响应结构
type BaseResponse struct {
	Code      ResponseCode `json:"code"`                 // 业务响应码
	Message   string       `json:"message"`              // 响应消息
	Data      interface{}  `json:"data,omitempty"`       // 响应数据
	RequestID string       `json:"request_id,omitempty"` // 请求ID
	Timestamp int64        `json:"timestamp"`            // 时间戳
	Success   bool         `json:"success"`              // 是否成功
}

// Response Swagger文档使用的响应类型别名
type Response = BaseResponse

// PaginationMeta 分页元数据
type PaginationMeta struct {
	Page       int   `json:"page"`        // 当前页码
	PageSize   int   `json:"page_size"`   // 每页大小
	Total      int64 `json:"total"`       // 总记录数
	TotalPages int   `json:"total_pages"` // 总页数
}

// PaginationResponse 分页响应结构
type PaginationResponse struct {
	BaseResponse
	Meta PaginationMeta `json:"meta"` // 分页元数据
}

// PageResponse Swagger文档使用的分页响应别名
type PageResponse = PaginationResponse

// ListResponse 列表响应结构
type ListResponse struct {
	BaseResponse
	Count int `json:"count"` // 列表项数量
}

// Responder 响应器接口
type Responder interface {
	// 成功响应
	Success(data interface{}, message ...string)
	SuccessWithMeta(data interface{}, meta interface{}, message ...string)

	// 分页响应
	Pagination(data interface{}, meta PaginationMeta, message ...string)

	// 列表响应
	List(data interface{}, message ...string)

	// 错误响应
	Error(err error)
	BusinessError(message string, code ...ResponseCode)
	ValidationError(message string, details ...interface{})
	NotFound(message ...string)
	Unauthorized(message ...string)
	Forbidden(message ...string)
	InternalError(message ...string)

	// 自定义响应
	Custom(code ResponseCode, message string, data interface{})

	// 原始响应（用于特殊情况）
	Raw(httpCode int, data interface{})
}

// GinResponder Gin框架响应器实现
type GinResponder struct {
	ctx       *gin.Context
	requestID string
}

// NewResponder 创建响应器
func NewResponder(ctx *gin.Context) Responder {
	requestID := getRequestID(ctx)
	return &GinResponder{
		ctx:       ctx,
		requestID: requestID,
	}
}

// Success 成功响应
func (r *GinResponder) Success(data interface{}, message ...string) {
	msg := "操作成功"
	if len(message) > 0 && message[0] != "" {
		msg = message[0]
	}

	r.respond(http.StatusOK, CodeSuccess, msg, data, true)
}

// SuccessWithMeta 带元数据的成功响应
func (r *GinResponder) SuccessWithMeta(data interface{}, meta interface{}, message ...string) {
	msg := "操作成功"
	if len(message) > 0 && message[0] != "" {
		msg = message[0]
	}

	response := struct {
		Data interface{} `json:"data"`
		Meta interface{} `json:"meta"`
	}{
		Data: data,
		Meta: meta,
	}

	r.respond(http.StatusOK, CodeSuccess, msg, response, true)
}

// Pagination 分页响应
func (r *GinResponder) Pagination(data interface{}, meta PaginationMeta, message ...string) {
	msg := "获取数据成功"
	if len(message) > 0 && message[0] != "" {
		msg = message[0]
	}

	response := PaginationResponse{
		BaseResponse: BaseResponse{
			Code:      CodeSuccess,
			Message:   msg,
			Data:      data,
			RequestID: r.requestID,
			Timestamp: time.Now().Unix(),
			Success:   true,
		},
		Meta: meta,
	}

	r.ctx.JSON(http.StatusOK, response)
}

// List 列表响应
func (r *GinResponder) List(data interface{}, message ...string) {
	msg := "获取列表成功"
	if len(message) > 0 && message[0] != "" {
		msg = message[0]
	}

	count := 0
	if dataSlice, ok := data.([]interface{}); ok {
		count = len(dataSlice)
	}

	response := ListResponse{
		BaseResponse: BaseResponse{
			Code:      CodeSuccess,
			Message:   msg,
			Data:      data,
			RequestID: r.requestID,
			Timestamp: time.Now().Unix(),
			Success:   true,
		},
		Count: count,
	}

	r.ctx.JSON(http.StatusOK, response)
}

// Error 错误响应
func (r *GinResponder) Error(err error) {
	if appErr, ok := errors.GetAppError(err); ok {
		httpCode := appErr.GetHTTPCode()
		code := ResponseCode(appErr.Code)
		r.respond(httpCode, code, appErr.Message, nil, false)
	} else {
		r.respond(http.StatusInternalServerError, CodeInternalError, "内部服务器错误", nil, false)
	}
}

// BusinessError 业务错误响应
func (r *GinResponder) BusinessError(message string, code ...ResponseCode) {
	respCode := CodeInternalError
	if len(code) > 0 {
		respCode = code[0]
	}

	httpCode := r.getHTTPCodeFromResponseCode(respCode)
	r.respond(httpCode, respCode, message, nil, false)
}

// ValidationError 验证错误响应
func (r *GinResponder) ValidationError(message string, details ...interface{}) {
	data := interface{}(nil)
	if len(details) > 0 {
		data = details[0]
		//message += details[0]
	}

	r.respond(http.StatusUnprocessableEntity, CodeValidationError, message, data, false)
}

// NotFound 未找到响应
func (r *GinResponder) NotFound(message ...string) {
	msg := "资源不存在"
	if len(message) > 0 && message[0] != "" {
		msg = message[0]
	}

	r.respond(http.StatusNotFound, CodeNotFound, msg, nil, false)
}

// Unauthorized 未授权响应
func (r *GinResponder) Unauthorized(message ...string) {
	msg := "未授权访问"
	if len(message) > 0 && message[0] != "" {
		msg = message[0]
	}

	r.respond(http.StatusUnauthorized, CodeUnauthorized, msg, nil, false)
}

// Forbidden 禁止访问响应
func (r *GinResponder) Forbidden(message ...string) {
	msg := "禁止访问"
	if len(message) > 0 && message[0] != "" {
		msg = message[0]
	}

	r.respond(http.StatusForbidden, CodeForbidden, msg, nil, false)
}

// InternalError 内部错误响应
func (r *GinResponder) InternalError(message ...string) {
	msg := "内部服务器错误"
	if len(message) > 0 && message[0] != "" {
		msg = message[0]
	}

	r.respond(http.StatusInternalServerError, CodeInternalError, msg, nil, false)
}

// Custom 自定义响应
func (r *GinResponder) Custom(code ResponseCode, message string, data interface{}) {
	httpCode := r.getHTTPCodeFromResponseCode(code)
	success := code == CodeSuccess
	r.respond(httpCode, code, message, data, success)
}

// Raw 原始响应
func (r *GinResponder) Raw(httpCode int, data interface{}) {
	r.ctx.JSON(httpCode, data)
}

// respond 统一响应方法
func (r *GinResponder) respond(httpCode int, code ResponseCode, message string, data interface{}, success bool) {
	response := BaseResponse{
		Code:      code,
		Message:   message,
		Data:      data,
		RequestID: r.requestID,
		Timestamp: time.Now().Unix(),
		Success:   success,
	}

	r.ctx.JSON(httpCode, response)
}

// getHTTPCodeFromResponseCode 从业务响应码获取HTTP状态码
func (r *GinResponder) getHTTPCodeFromResponseCode(code ResponseCode) int {
	switch code {
	case CodeSuccess:
		return http.StatusOK
	case CodeBadRequest:
		return http.StatusBadRequest
	case CodeUnauthorized:
		return http.StatusUnauthorized
	case CodeForbidden:
		return http.StatusForbidden
	case CodeNotFound:
		return http.StatusNotFound
	case CodeValidationError:
		return http.StatusUnprocessableEntity
	case CodeTooManyRequests:
		return http.StatusTooManyRequests
	case CodeServiceError:
		return http.StatusServiceUnavailable
	case CodeTimeout:
		return http.StatusGatewayTimeout
	default:
		return http.StatusInternalServerError
	}
}

// getRequestID 获取请求ID
func getRequestID(ctx *gin.Context) string {
	if requestID := ctx.GetHeader("X-Request-ID"); requestID != "" {
		return requestID
	}

	if requestID := ctx.GetString("request_id"); requestID != "" {
		return requestID
	}

	// 生成默认请求ID
	return generateRequestID()
}

// generateRequestID 生成请求ID
func generateRequestID() string {
	// 使用时间戳+随机数生成短UUID风格ID
	// 生成类似: req_2f4a1b8c
	timestamp := uint32(time.Now().Unix())
	random := uint32(time.Now().UnixNano())

	// 组合时间戳和随机数
	combined := uint64(timestamp)<<32 | uint64(random)

	// 转换为16进制，取前8位
	hex := fmt.Sprintf("%016x", combined)[:8]

	return "req_" + hex
}

// 便利函数已在middleware.go中定义
//
//// BadRequest 400错误便利函数
//func BadRequest(ctx *gin.Context, message string, details ...interface{}) {
//	responder := NewResponder(ctx)
//	if len(details) > 0 {
//		responder.ValidationError(message, details[0])
//	} else {
//		responder.BusinessError(message, CodeBadRequest)
//	}
//}
//
//// Unauthorized 401错误便利函数
//func Unauthorized(ctx *gin.Context, message string) {
//	NewResponder(ctx).Unauthorized(message)
//}
//
//// Forbidden 403错误便利函数
//func Forbidden(ctx *gin.Context, message string) {
//	NewResponder(ctx).Forbidden(message)
//}
//
//// NotFound 404错误便利函数
//func NotFound(ctx *gin.Context, message string) {
//	NewResponder(ctx).NotFound(message)
//}
//
//// InternalServerError 500错误便利函数
//func InternalServerError(ctx *gin.Context, message string) {
//	NewResponder(ctx).InternalError(message)
//}
